package com.soriya.nestlive.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.soriya.nestlive.common.GlobalThreadLocal;
import com.soriya.nestlive.entity.ChannelEntity;
import com.soriya.nestlive.entity.PageResult;
import com.soriya.nestlive.entity.UserChannelEntity;
import com.soriya.nestlive.entity.UserEntity;
import com.soriya.nestlive.entity.param.ChannelListParam;
import com.soriya.nestlive.entity.vo.ChannelDetailVo;
import com.soriya.nestlive.mapper.ChannelMapper;
import com.soriya.nestlive.service.ChannelService;
import com.soriya.nestlive.service.UserChannelService;
import com.soriya.nestlive.util.excpetion.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ChannelServiceImpl extends ServiceImpl<ChannelMapper, ChannelEntity> implements ChannelService {

    @Autowired
    private UserChannelService userChannelService;

    @Override
    public PageResult<ChannelEntity> pageQuery(Page<ChannelEntity> page, ChannelListParam param) {
        LambdaQueryWrapper<ChannelEntity> wrapper = new LambdaQueryWrapper<>();
        page(page, wrapper);
        return PageResult.from(page);
    }

    @Override
    public ChannelDetailVo getByUserId() {
        Long userId = GlobalThreadLocal.getUserId();

        MPJLambdaWrapper<ChannelEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(ChannelEntity.class)
                .select(UserEntity::getAvatar)
                .select(UserEntity::getNickname)
                .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId)
                .eq(ChannelEntity::getUserId, userId)
                .last("LIMIT 1");

        return baseMapper.selectJoinOne(ChannelDetailVo.class, wrapper);
    }

    @Override
    public PageResult<ChannelDetailVo> follow(Long userId, Integer current, Integer size) {
        current = current == null ? 1 : current;
        size = size == null ? 6 : size;

        Page<ChannelDetailVo> page = new Page<>(current, size);

        MPJLambdaWrapper<ChannelEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(ChannelEntity.class)
                .select(UserEntity::getAvatar)
                .select(UserEntity::getNickname)
                .rightJoin(UserChannelEntity.class, UserChannelEntity::getChannelId, ChannelEntity::getId)
                .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId)
                .eq(UserChannelEntity::getUserId, userId);

        baseMapper.selectJoinPage(page, ChannelDetailVo.class, wrapper);

        return PageResult.from(page);
    }

    @Override
    public PageResult<ChannelDetailVo> getRecommendChannel(Integer current, Integer size) {
        Long userId = GlobalThreadLocal.getUserId();

        Page<ChannelDetailVo> page = new Page<>(current, size);
        MPJLambdaWrapper<ChannelEntity> wrapper = new MPJLambdaWrapper<>();
        if (userId == 0) {
            wrapper.selectAll(ChannelEntity.class)
                    .select(UserEntity::getAvatar)
                    .select(UserEntity::getNickname)
                    .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId);

            baseMapper.selectJoinPage(page, ChannelDetailVo.class, wrapper);
            return PageResult.from(page);
        } else {
            int position = (current - 1) * size;

            int total = baseMapper.selectRecommendCount(userId);
            List<ChannelDetailVo> list = baseMapper.selectRecommend(userId, position, size);

            return new PageResult<>(total, size, total / size, position, list);
        }
    }

    @Override
    public ChannelDetailVo getDetailById(Long id) {

        MPJLambdaWrapper<ChannelEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(ChannelEntity.class)
                .select(UserEntity::getAvatar)
                .select(UserEntity::getNickname)
                .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId)
                .eq(ChannelEntity::getId, id)
                .last("LIMIT 1");

        ChannelDetailVo channelDetailVo = baseMapper.selectJoinOne(ChannelDetailVo.class, wrapper);

        Long userId = GlobalThreadLocal.getUserId();

        if (userId != 0) {
            int count = userChannelService.count(new LambdaQueryWrapper<UserChannelEntity>()
                    .eq(UserChannelEntity::getChannelId, id)
                    .eq(UserChannelEntity::getUserId, userId));

            channelDetailVo.setIsFollow(count > 0 ? 1 : 0);
        }

        return channelDetailVo;
    }

    @Override
    public boolean followChannel(Long channelId) {
        Long userId = GlobalThreadLocal.getUserId();

        if (userId == 0) throw new MyException("用户未登录");

        UserChannelEntity one = userChannelService.getOne(new LambdaQueryWrapper<UserChannelEntity>()
                .eq(UserChannelEntity::getChannelId, channelId)
                .eq(UserChannelEntity::getUserId, userId));

        if (one != null) throw new MyException("用户已关注该频道");

        UserChannelEntity userChannelEntity = new UserChannelEntity();
        userChannelEntity.setUserId(userId);
        userChannelEntity.setChannelId(channelId);

        return userChannelService.save(userChannelEntity);
    }


}
